package code;

import java.io.FileReader;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

/**
 *
 * @author Mr. Butkus
 */

/**
 * Operacijos kodu enumeratorius
 */
enum OPC {
    PUSH("PUSH"), POP_("POP_"), ADD_("ADD_"), SUB_("SUB_"), CMP_("CMP_"), JMPT("JMPT"),
    GD__("GD__"), PUT_("PUT_"), JMPF("JMPF"), JMP_("JMP_"), HALT("HALT"), MUL_("MUL_"),
    CREA("CREA"), DELE("DELE"), OPEN("OPEN"), CLOS("CLOS"), READ("READ"), WRIT("WRIT");
    
    private OPC(String str) {
    	this.value = str;
    }
    
    private final String value;
}

public class VirtualMachine {
	
	//---- Constants
	
    public static final int VM_MEMORY_SIZE = 256;
	
	//---- Fields
	
	private int id;                  // ID

        
    String s;
    InputStreamReader isr = new InputStreamReader(System.in);
    BufferedReader br = new BufferedReader(isr);

    //---- Fields
    private boolean stop;                   // VM busena
    private RealMachine rm;                // rodykle i RM
    public Vector input = new Vector();     // virtualus ivedimo irenginys
    public Vector output = new Vector();    // virtualus isvedimo irenginys
    String currentlyOpenedFile;
    int i; // for READ and WRIT only        
	
	//---- Methods
	
	/**
	 * Constructor
	 * @param rm
	 */
	public VirtualMachine(int id, RealMachine rm) {
		this.id = id;
		this.rm = rm;
		this.stop = false;
		this.rm.allocateMemory();    //RM isskiria atminties VM ir sukuria puslapiu lentele
	}
	
	/**
	 * Constructor 2
	 */
	public VirtualMachine() {
	}

    public Vector getOutput()
    {
        return this.output;
    }

    public void resetOutput()
    {
        this.output.clear();
    }

    public boolean getStop()
    {
        return this.stop;
    }

    public void resetStop()
    {
        this.stop = false;
    }        
        
	/**
	 * Is failo nuskaitom programa i atminti
	 */
public void loadProgram()
{
    String record = null;
    char[] tmp = null;
    int x = 0, y = 0;
    char seg = 0;
    int adr = 0;

    try
    {
        FileReader fr = new FileReader(rm.getUserProgram());
        BufferedReader brr = new BufferedReader(fr);

        while ((record = brr.readLine()).compareTo("$END") != 0)
        {
            tmp = record.toCharArray();    //record saugo stringa is 4 elementu


            if (String.valueOf(tmp).compareTo("DSEG") == 0)
            {
                seg = 'D';
                adr = rm.getDS();
            } else if (String.valueOf(tmp).compareTo("CSEG") == 0)
            {
                seg = 'C';
                adr = rm.getCS();
            } else if (tmp[0] == '$' && seg == 'D')
            {
                record = brr.readLine();
                tmp = record.toCharArray();
                adr += rm.hexToDec(record);
            } else
            {
                //kraunam i atminti pagal realu adresa
           //     System.out.println("adr="+adr+"adr");
           //     System.out.println("real="+rm.getRealAddress(adr)+"real");
                rm.memory[rm.getRealAddress(adr)].a = tmp[0];
                rm.memory[rm.getRealAddress(adr)].b = tmp[1];
                rm.memory[rm.getRealAddress(adr)].c = tmp[2];
                rm.memory[rm.getRealAddress(adr)].d = tmp[3];
                adr++;
            }

        }
        brr.close();
        fr.close();
    } catch (IOException e)
    {
        System.out.println("Klaida nuskaitant faila");
        e.printStackTrace();
    }

}

        
        
	
	/**
	 * Gaunam ID
	 * @return id
	 */
	public int getID(){
		return this.id;
	}
	
	/**
	 * Nustatom lauko stop reiksme
	 * @param stop
	 */
	public void setStop(boolean stop){
		this.stop = stop;
	}
	
	/**
	 * Gaunam lauko stop reiksme
	 * @return stop
	 */

}
